<?php

namespace app\api\controller;

use think\Db;
use think\Image;
use OSS\OssClient;
use app\api\model\VolleyDesc as Balance;
use app\api\model\Task;

class Faceid extends Common
{
    protected $expired;
    protected $token;
    protected $result;

    public function _initialize()
    {
        parent::_initialize();

        $this->expired = '3600';
        $this->token = 'https://api.megvii.com/faceid/v3/sdk/get_biz_token';
        $this->result = 'https://api.megvii.com/faceid/v3/sdk/verify';
    }

    /**
     * 步骤一，客户端调用get_biz_token()获取token 进行识别。
     * 步骤二，客户端调用auth(进行验证识别结果)
     */

    // 人脸识别 获取签名
    public function gen_sign()
    {
        $rdm = rand();
        $current_time = time();
        $expired_time = $current_time + $this->expired;
        $srcStr = "a=%s&b=%d&c=%d&d=%d";
        $srcStr = sprintf($srcStr, getenv('FACE_KEY'), $expired_time, $current_time, $rdm);
        $sign = base64_encode(hash_hmac('SHA1', $srcStr, getenv('FACE_SECRET'), true) . $srcStr);

        return $sign;
    }

    // 人脸识别提交数据
    public function biz_token($uuid = '', $parm1 = '', $parm2 = '')
    {
        $data = [
            'sign' => $this->gen_sign(),
            'sign_version' => 'hmac_sha1',
            'liveness_type' => 'meglive',
        ];

        if ($uuid) { // 上传照片验证
            $data['comparison_type'] = 0;
            $data['image_ref1'] = $parm1;
            $data['uuid'] = $uuid;
            !$parm2 ?: $data['image_ref2'] = $parm2;
        } else { // 上传身份证验证
            $data['comparison_type'] = 1;
            $data['idcard_name'] = $parm1;
            $data['idcard_number'] = $parm2;
        }

        //初使化init方法
        $ch = curl_init();

        //指定URL
        curl_setopt($ch, CURLOPT_URL, $this->token);
        //设定请求后返回结果
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //声明使用POST方式来进行发送
        curl_setopt($ch, CURLOPT_POST, 1);
        //发送什么数据呢
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        //忽略证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        //忽略header头信息
        curl_setopt($ch, CURLOPT_HEADER, 0);

        //发送请求
        $output = curl_exec($ch);
        //关闭curl
        curl_close($ch);

        //返回数据
        return $output;
    }

    // 人脸识别提交数据(token返回前端。将图片及token存到数据表)
    public function get_biz_token()
    {
        $idcard_name = input('idcard_name') ? input('idcard_name') : '';
        $idcard_number = input('idcard_number') ? input('idcard_number') : '';

        $user_id = input('user_id');
        if (!$user_id) return json(['code' => 400, 'data' => '请先登录']);

        $attestation = Db::name('user')->where(['id' => $user_id])->value('attestation');
        if ($attestation) return json(['code' => 400, 'msg' => '已认证过']);

        /*$res = Db::name('auth')->where(['user_id' => $user_id])->find();
        if ($res) {
            if (($res['create_time'] + config('faceid')['expired']) > time()) {
                return json(['code' => 200, 'data' => $res['token']]);
            }
        }*/

        $image_ref1 = '';
        $image_ref2 = '';
        $image1 = '';
        $image2 = '';

        if ($idcard_name) {
            $data = [
                'sign' => $this->gen_sign(),
                'sign_version' => 'hmac_sha1',
                'liveness_type' => 'meglive',
                'comparison_type' => 1,
                'idcard_name' => $idcard_name,
                'idcard_number' => $idcard_number,
            ];
        } else {
            if (isset($_FILES['image_ref1'])) {
                $file_obj = curl_file_create(realpath($_FILES['image_ref1']['tmp_name']), 'image/png', 'image_ref1.png');
                $image_ref1 = $file_obj;
                $image1 = $this->imagesUpload(request()->file("image_ref1"));

                $file=iconv("UTF-8","gb2312", $image1);
                $image_ref1=new \CURLFile($file);
            }
            if (isset($_FILES['image_ref2'])) {
                $file_obj = curl_file_create(realpath($_FILES['image_ref2']['tmp_name']), 'image/png', 'image_ref2.png');
                $image_ref2 = $file_obj;
                $image2 = $this->imagesUpload(request()->file("image_ref2"));

                $file=iconv("UTF-8","gb2312", $image2);
                $image_ref2=new \CURLFile($file);
            }

            $data = [
                'sign' => $this->gen_sign(),
                'sign_version' => 'hmac_sha1',
                'liveness_type' => 'meglive',
                'comparison_type' => 0,
                'image_ref1' => $image_ref1,
                'uuid' => '123456789',
            ];

            if ($image_ref2) {
                $data['image_ref2'] = $image_ref2;
            }
        }

        //初使化init方法
        $ch = curl_init();

        //指定URL
        curl_setopt($ch, CURLOPT_URL, $this->token);
        //设定请求后返回结果
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //声明使用POST方式来进行发送
        curl_setopt($ch, CURLOPT_POST, 1);
        //发送什么数据呢
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        //忽略证书
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //忽略header头信息
        curl_setopt($ch, CURLOPT_HEADER, 0);

        //发送请求
        $output = curl_exec($ch);
        //关闭curl
        curl_close($ch);

        //返回数据
        $result = $output;

        $token = json_decode($result, true);
        $biztoken = isset($token['biz_token']) ? $token['biz_token'] : 0;

        if (!$biztoken) {
            return json(['code' => 400, 'msg' => $token['error']]);
        } else {
            Db::name('auth')->where(['user_id' => $user_id])->delete();

            Db::name('auth')->insert([
                'user_id' => $user_id,
                'idcard_name' => $idcard_name,
                'idcard_number' => $idcard_number,
                'image_ref1' => $image_ref1,
                'image_ref2' => $image_ref2,
                'image1' => $image1 ? '/'.$image1 : '',
                'image2' => $image2 ? '/'.$image2 : '',
                'token' => $biztoken,
                'create_time' => time()
            ]);

            return json(['code' => 200, 'data' => $biztoken]);
        }
    }

    public function bizresult($token, $meglive_data='')
    {
        $data = [
            'sign' => $this->gen_sign(),
            'sign_version' => 'hmac_sha1',
            'biz_token' => $token,
        ];

        if ($meglive_data) { // 上传身份证验证
            $data['meglive_data'] = new \CURLFile(realpath($meglive_data['tmp_name']), $meglive_data['type'], $meglive_data['name']);
        } else { // 上传照片验证
            $query = http_build_query($data);
        }

        //初使化init方法
        $ch = curl_init();

        //指定URL
        curl_setopt($ch, CURLOPT_URL, $this->result);
        if ($meglive_data) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        } else {
            curl_setopt($ch, CURLOPT_URL, $this->result . '?' . $query);
        }
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //发送请求
        $output = curl_exec($ch);

        //关闭curl
        curl_close($ch);

        //返回数据
        return $output;
    }

    public function auth()
    {
        $user_id = input('user_id/d');
        $meglive_data = isset($_FILES['meglive_data']) ? $_FILES['meglive_data'] : '';
        $uuid = $meglive_data ? (input('uuid') ? input('uuid') : '123456789') : '';

        if (!$user_id) return json(['code' => 400, 'msg' => '请先登录再进行']);
        $attestation = Db::name('user')->where(['id' => $user_id])->value('attestation');
        if ($attestation) return json(['code' => 400, 'msg' => '已认证过']);

        // 去表里查询是否有上传过照片，如果有，先看biztoken是否已过期，如果过期，将以前上传存到表里的照片重新传到接口biz_token()获取token
        $res = Db::name('auth')->where(['user_id' => $user_id])->find();
        if ($res) {
            if (($res['create_time'] + $this->expired) > time()) {
                $biztoken = $res['token'];
            } else {
                $image_ref1 = json_decode($res['image_ref1']);
                $image_ref2 = json_decode($res['image_ref2']);

                /*if (!$image_ref1 && !$image_ref2) return json(['code' => 400, 'msg' => '至少需上传一张照片']);*/

                $token = $meglive_data ? $this->biz_token($uuid, $res['idcard_name'], $res['idcard_number']) : $this->biz_token($uuid, $image_ref1, $image_ref2);
                $token = json_decode($token, true);
                $biztoken = isset($token['biz_token']) ? $token['biz_token'] : 0;
                if (!$biztoken) return json(['code' => 400, 'msg' => $token['error']]);
            }
        } else {
            return json(['code' => 400, 'msg' => '请重新验证']);
        }

        $getResult = $this->bizresult($biztoken, $meglive_data);
        $getResult = json_decode($getResult, true);

        if ($getResult['result_code'] != 1000) return json(['code' => 400, 'msg' => $getResult['result_message']]);

        $res = Db::name('auth')->where(['user_id' => $user_id])->find();
        if ($res['image1']) {

            Db::name('user_img')->insert([
                'user_id' => $user_id,
                'pic' => json_encode([$res['image1']]),
                'picthumb' => json_encode([$res['image1']]),
                'burn' => 0,
                'packet' => 0,
                'is_auth' => 1,
                'is_face' => 1
            ]);
        }

        // 任务
        Task::finish('real_auth', $user_id);

        Db::name('user')->where(['id' => $user_id])->update([
            // 'head_100' => $res['image1'],
            // 'head_300' => $res['image1'],
            // 'head_portrait' => $res['image1'],
            'attestation' => 1,
            'is_identity_authentication' => 2
        ]);
        return json(['code' => 200, 'msg' => 'success']);
    }

    //-------------------------------------------------------------

    // 上传图片
    private function imagesUpload($file)
    {
        $switch = getenv('APP_OSS');

        $image = Image::open($file);

        $path = ROOT_PATH . 'disk' . DS . 'uploads' . DS . 'images';
        $info = $file->move($path);

        if ($info) {
            $img = $fileName = 'disk/uploads/images/' . $info->getSaveName();
            $img = str_replace('\\', '/', $img);

            $image->thumb(1000, 1000)->save($img);

            if ($switch) {
                $localFile = str_replace('/index.php', '', $_SERVER['SCRIPT_FILENAME']) . '/'.$img;

                $accessKeyId = getenv('OSS_KEYID');
                $accessKeySecret = getenv('OSS_KEYSECRET');
                $endpoint = getenv('OSS_ENDPOINT');
                $bucket = getenv('OSS_BUCKET');

                $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
                $ossClient->uploadFile($bucket, $fileName, $localFile);

                //unlink($localFile);
            }

            return $img;
        } else {
            return $file->getError();
        }
    }


    
}
